package com.designpattern.creating.singleton;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author chengzelee
 * @Date 2022/11/24 18:49
 * @Desc CAS实现单例
 */
public class Singleton_CAS {

    private static final AtomicReference<Singleton_CAS> INSTANCE = new AtomicReference<>();

    private static Singleton_CAS instance;

    /**
     * 因为创建对象是原子操作，故不受其他线程影响
     * 对象的获取 INSTANCE.get() 在 compareAndSet() 之后，一定能获取到对象
     */
    public static Singleton_CAS getInstance(){
        instance = INSTANCE.get();
        if (instance != null){
            return instance;
        }
        // 如果 expectedValue 符合预期，执行原子操作
        INSTANCE.compareAndSet(null, new Singleton_CAS());
        return INSTANCE.get();
    }

    /**
     * 错误示例
     */
    public static Singleton_CAS falseExample(){
        for (;;){
            instance = INSTANCE.get();
            if (instance != null){
                return instance;
            }
            // 如果 compareAndSet 是 true ，说明 instance 此时为 null，去下一次循环拿，不直接返回
            // 但如果 compareAndSet 是 false ，而 instance 是在这次判断之前赋值的，可能赋值时为null，但判断时已被其他线程创建了对象，从而返回 null
            if (!INSTANCE.compareAndSet(null, new Singleton_CAS())){
                return instance;
            }
        }
    }

}
